#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_TRAINS 100
#define FILENAME "train_data.dat"
#define BOOKING_FILE "bookings.dat"

// 火车票信息结构体
typedef struct {
    char number[20];        // 车次
    char start[50];         // 始发站
    char destination[50];   // 终点站
    char depart_time[10];   // 发车时间
    char arrive_time[10];   // 到达时间
    float price;            // 票价
    int total_seats;        // 总座位数
    int available_seats;    // 可用座位数
} Train;

// 订票信息结构体
typedef struct {
    char train_number[20];  // 车次
    char name[50];          // 订票人姓名
    char id[20];            // 身份证号
} Booking;

// 全局变量
Train trains[MAX_TRAINS];
int train_count = 0;
Booking bookings[MAX_TRAINS * 100];
int booking_count = 0;

// 函数声明
void load_data();
void save_data();
void add_train();
void search_trains();
void book_ticket();
void modify_train();
void show_trains();
void save_bookings();
void show_bookings();
void clear_input_buffer();

int main() {
    // 设置控制台编码为UTF-8 (Windows)
    #if defined(_WIN32) || defined(_WIN64)
    system("chcp 65001 > nul");
    #endif
    
    load_data();
    
    int choice;
    do {
        printf("\n火车票订票系统\n");
        printf("1. 添加火车信息\n");
        printf("2. 查询火车信息\n");
        printf("3. 订票\n");
        printf("4. 修改火车信息\n");
        printf("5. 显示所有火车信息\n");
        printf("6. 显示订票信息\n");
        printf("0. 退出系统\n");
        printf("请选择操作: ");
        if (scanf("%d", &choice) != 1) {
            clear_input_buffer();
            printf("输入无效，请输入数字\n");
            continue;
        }
        clear_input_buffer();
        
        switch(choice) {
            case 1: add_train(); break;
            case 2: search_trains(); break;
            case 3: book_ticket(); break;
            case 4: modify_train(); break;
            case 5: show_trains(); break;
            case 6: show_bookings(); break;
            case 0: 
                save_data(); 
                printf("数据已保存，谢谢使用!\n");
                break;
            default: 
                printf("无效选择，请重新输入!\n");
        }
    } while(choice != 0);
    
    return 0;
}

// 清除输入缓冲区
void clear_input_buffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

// 加载数据
void load_data() {
    FILE *file = fopen(FILENAME, "rb");
    if (file == NULL) {
        return; // 文件不存在是正常情况
    }
    
    // 读取火车数据
    fread(&train_count, sizeof(int), 1, file);
    if (train_count > 0 && train_count <= MAX_TRAINS) {
        fread(trains, sizeof(Train), train_count, file);
    }
    fclose(file);
    
    // 加载订票信息
    FILE *bfile = fopen(BOOKING_FILE, "rb");
    if (bfile != NULL) {
        fread(&booking_count, sizeof(int), 1, bfile);
        if (booking_count > 0 && booking_count <= MAX_TRAINS * 100) {
            fread(bookings, sizeof(Booking), booking_count, bfile);
        }
        fclose(bfile);
    }
}

// 保存数据
void save_data() {
    // 保存火车数据
    FILE *file = fopen(FILENAME, "wb");
    if (file != NULL) {
        fwrite(&train_count, sizeof(int), 1, file);
        fwrite(trains, sizeof(Train), train_count, file);
        fclose(file);
    }
    
    // 保存订票信息
    save_bookings();
}

// 添加火车信息
void add_train() {
    if (train_count >= MAX_TRAINS) {
        printf("火车信息已满，无法添加!\n");
        return;
    }
    
    Train new_train;
    printf("\n输入车次: ");
    if (scanf("%19s", new_train.number) != 1) {
        printf("输入无效\n");
        clear_input_buffer();
        return;
    }
    clear_input_buffer();
    
    // 检查车次是否已存在
    for (int i = 0; i < train_count; i++) {
        if (strcmp(trains[i].number, new_train.number) == 0) {
            printf("该车次已存在!\n");
            return;
        }
    }
    
    printf("输入始发站: ");
    fgets(new_train.start, sizeof(new_train.start), stdin);
    new_train.start[strcspn(new_train.start, "\n")] = '\0';
    
    printf("输入终点站: ");
    fgets(new_train.destination, sizeof(new_train.destination), stdin);
    new_train.destination[strcspn(new_train.destination, "\n")] = '\0';
    
    printf("输入发车时间(HH:MM): ");
    scanf("%9s", new_train.depart_time);
    clear_input_buffer();
    
    printf("输入到达时间(HH:MM): ");
    scanf("%9s", new_train.arrive_time);
    clear_input_buffer();
    
    printf("输入票价: ");
    if (scanf("%f", &new_train.price) != 1) {
        printf("票价无效，使用默认值 0.0\n");
        new_train.price = 0.0;
    }
    clear_input_buffer();
    
    printf("输入总座位数: ");
    if (scanf("%d", &new_train.total_seats) != 1 || new_train.total_seats <= 0) {
        printf("座位数无效，使用默认值 100\n");
        new_train.total_seats = 100;
    }
    clear_input_buffer();
    
    new_train.available_seats = new_train.total_seats;
    
    trains[train_count++] = new_train;
    save_data();
    printf("火车信息添加成功!\n");
}

// 查询火车信息
void search_trains() {
    int choice;
    printf("\n查询方式:\n");
    printf("1. 按车次查询\n");
    printf("2. 按城市查询\n");
    printf("请选择: ");
    if (scanf("%d", &choice) != 1) {
        printf("输入无效\n");
        clear_input_buffer();
        return;
    }
    clear_input_buffer();
    
    if (choice == 1) {
        char number[20];
        printf("输入车次: ");
        scanf("%19s", number);
        clear_input_buffer();
        
        for (int i = 0; i < train_count; i++) {
            if (strcmp(trains[i].number, number) == 0) {
                printf("\n车次: %s\n", trains[i].number);
                printf("路线: %s -> %s\n", trains[i].start, trains[i].destination);
                printf("时间: %s - %s\n", trains[i].depart_time, trains[i].arrive_time);
                printf("票价: %.2f元\n", trains[i].price);
                printf("可用座位: %d/%d\n", trains[i].available_seats, trains[i].total_seats);
                return;
            }
        }
        printf("未找到该车次!\n");
        
    } else if (choice == 2) {
        char city[50];
        printf("输入城市: ");
        fgets(city, sizeof(city), stdin);
        city[strcspn(city, "\n")] = '\0';
        
        printf("\n开往 %s 的列车信息:\n", city);
        printf("===============================================\n");
        printf("车次\t始发站\t终点站\t发车时间\t到达时间\t票价\t余票\n");
        printf("===============================================\n");
        
        int found = 0;
        for (int i = 0; i < train_count; i++) {
            if (strcmp(trains[i].destination, city) == 0) {
                printf("%s\t%s\t%s\t%s\t%s\t%.2f\t%d/%d\n", 
                      trains[i].number, 
                      trains[i].start, 
                      trains[i].destination,
                      trains[i].depart_time,
                      trains[i].arrive_time,
                      trains[i].price,
                      trains[i].available_seats,
                      trains[i].total_seats);
                found = 1;
            }
        }
        
        if (!found) {
            printf("未找到开往该城市的列车!\n");
        }
    } else {
        printf("无效选择!\n");
    }
}

// 订票功能
void book_ticket() {
    if (train_count == 0) {
        printf("没有可订票的火车信息\n");
        return;
    }
    
    char city[50];
    printf("\n请输入目的地城市: ");
    fgets(city, sizeof(city), stdin);
    city[strcspn(city, "\n")] = '\0';
    
    // 显示符合条件的列车
    printf("\n开往 %s 的可用列车:\n", city);
    printf("===============================================\n");
    printf("序号\t车次\t发车时间\t到达时间\t票价\t余票\n");
    printf("===============================================\n");
    
    int valid_trains[MAX_TRAINS];
    int valid_count = 0;
    
    for (int i = 0; i < train_count; i++) {
        if (strcmp(trains[i].destination, city) == 0 && trains[i].available_seats > 0) {
            printf("%d\t%s\t%s\t%s\t%.2f\t%d\n", 
                  valid_count + 1,
                  trains[i].number, 
                  trains[i].depart_time,
                  trains[i].arrive_time,
                  trains[i].price,
                  trains[i].available_seats);
            valid_trains[valid_count++] = i;
        }
    }
    
    if (valid_count == 0) {
        printf("没有可用列车!\n");
        return;
    }
    
    int choice;
    printf("\n请选择列车序号: ");
    if (scanf("%d", &choice) != 1) {
        printf("输入无效\n");
        clear_input_buffer();
        return;
    }
    clear_input_buffer();
    
    if (choice < 1 || choice > valid_count) {
        printf("无效选择!\n");
        return;
    }
    
    int train_index = valid_trains[choice - 1];
    
    // 输入订票人信息
    Booking new_booking;
    strcpy(new_booking.train_number, trains[train_index].number);
    
    printf("输入订票人姓名: ");
    fgets(new_booking.name, sizeof(new_booking.name), stdin);
    new_booking.name[strcspn(new_booking.name, "\n")] = '\0';
    
    printf("输入身份证号: ");
    fgets(new_booking.id, sizeof(new_booking.id), stdin);
    new_booking.id[strcspn(new_booking.id, "\n")] = '\0';
    
    // 更新座位信息
    trains[train_index].available_seats--;
    
    // 保存订票信息
    bookings[booking_count++] = new_booking;
    
    save_data();
    printf("\n订票成功!\n");
    printf("车次: %s\n", new_booking.train_number);
    printf("姓名: %s\n", new_booking.name);
    printf("身份证: %s\n", new_booking.id);
}

// 修改火车信息
void modify_train() {
    if (train_count == 0) {
        printf("没有可修改的火车信息\n");
        return;
    }
    
    char number[20];
    printf("输入要修改的车次: ");
    scanf("%19s", number);
    clear_input_buffer();
    
    for (int i = 0; i < train_count; i++) {
        if (strcmp(trains[i].number, number) == 0) {
            printf("\n当前信息:\n");
            printf("车次: %s\n", trains[i].number);
            printf("始发站: %s\n", trains[i].start);
            printf("终点站: %s\n", trains[i].destination);
            printf("发车时间: %s\n", trains[i].depart_time);
            printf("到达时间: %s\n", trains[i].arrive_time);
            printf("票价: %.2f\n", trains[i].price);
            printf("总座位数: %d\n", trains[i].total_seats);
            printf("可用座位: %d\n", trains[i].available_seats);
            
            printf("\n输入新信息(留空回车保持原值):\n");
            
            char input[100];
            printf("新始发站 [%s]: ", trains[i].start);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                input[strcspn(input, "\n")] = '\0';
                strcpy(trains[i].start, input);
            }
            
            printf("新终点站 [%s]: ", trains[i].destination);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                input[strcspn(input, "\n")] = '\0';
                strcpy(trains[i].destination, input);
            }
            
            printf("新发车时间 [%s]: ", trains[i].depart_time);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                input[strcspn(input, "\n")] = '\0';
                strcpy(trains[i].depart_time, input);
            }
            
            printf("新到达时间 [%s]: ", trains[i].arrive_time);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                input[strcspn(input, "\n")] = '\0';
                strcpy(trains[i].arrive_time, input);
            }
            
            printf("新票价 [%.2f]: ", trains[i].price);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                trains[i].price = atof(input);
            }
            
            // 修复：修改总座位数时同步更新可用座位数
            printf("新总座位数 [%d]: ", trains[i].total_seats);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                int new_total = atoi(input);
                if (new_total >= trains[i].total_seats - trains[i].available_seats) {
                    // 计算已售座位数
                    int sold_seats = trains[i].total_seats - trains[i].available_seats;
                    // 更新总座位数
                    trains[i].total_seats = new_total;
                    // 更新可用座位数 = 新总座位数 - 已售座位数
                    trains[i].available_seats = new_total - sold_seats;
                } else {
                    printf("总座位数不能小于已售座位数(%d)!\n", 
                          trains[i].total_seats - trains[i].available_seats);
                }
            }
            
            save_data();
            printf("信息更新成功!\n");
            return;
        }
    }
    
    printf("未找到该车次!\n");
}

// 显示所有火车信息
void show_trains() {
    if (train_count == 0) {
        printf("没有火车信息可显示!\n");
        return;
    }
    
    printf("\n所有列车信息:\n");
    printf("=================================================================\n");
    printf("车次\t始发站\t终点站\t发车时间\t到达时间\t票价\t余票/总数\n");
    printf("=================================================================\n");
    
    for (int i = 0; i < train_count; i++) {
        printf("%s\t%s\t%s\t%s\t%s\t%.2f\t%d/%d\n", 
              trains[i].number, 
              trains[i].start, 
              trains[i].destination,
              trains[i].depart_time,
              trains[i].arrive_time,
              trains[i].price,
              trains[i].available_seats,
              trains[i].total_seats);
    }
}

// 保存订票信息
void save_bookings() {
    FILE *file = fopen(BOOKING_FILE, "wb");
    if (file != NULL) {
        fwrite(&booking_count, sizeof(int), 1, file);
        fwrite(bookings, sizeof(Booking), booking_count, file);
        fclose(file);
    }
}

// 显示订票信息
void show_bookings() {
    if (booking_count == 0) {
        printf("没有订票信息可显示!\n");
        return;
    }
    
    printf("\n所有订票信息:\n");
    printf("===============================================\n");
    printf("车次\t姓名\t身份证号\n");
    printf("===============================================\n");
    
    for (int i = 0; i < booking_count; i++) {
        printf("%s\t%s\t%s\n", 
              bookings[i].train_number,
              bookings[i].name,
              bookings[i].id);
    }
}